/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.transas.zorlog.data.log;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;

/**
 *
 * @author amalikov
 */
public class GcsPacketReader extends PacketReader {
	public GcsPacketReader(InputStream in) {
		super(in);
	}
	
	@Override
	public ByteBuffer getPacket() throws IOException {
		while (true) {
			byte[] t = new byte[4];
		
			if (in.read(t) == -1)
				return null;	/* end of stream */
		
			int size = ByteBuffer.wrap(t).order(ByteOrder.LITTLE_ENDIAN).get(2) & 0xFF;
			
			if (size < 4)
				continue;
			
			byte[] buf = Arrays.copyOf(t, size);
		
			if (in.read(buf, 4, size - 4) == -1)
				return null;	/* end of stream */
		
			if (getCrc(buf, size - 1) == ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN).get(size - 1))
				return ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN);
		}
	}

	@Override
	public int getId(ByteBuffer packet) {
		return (int)(packet.get(1) & 0xFF);
	}
	
	/**
	 * Returns the CRC8 value for the given byte array
	 * @param data - array of bytes
	 * @param size - number of bytes
	 */
	private byte getCrc(final byte[] data, int size) {
		byte crc = (byte)0xFF;
		
		for (int i = 0; i < size; ++i) {
			crc ^= data[i];
			
			for (int j = 0; j < 8; ++j)
				crc = (byte)(((crc & 0x80) != 0) ? (crc << 1) ^ 0x31 : (crc << 1));
		}
		
		return crc;
	}
	
}
